package com.zzh.partnersys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzh.partnersys.common.exception.BusinessException;
import com.zzh.partnersys.common.exception.ResultCodeEnum;
import com.zzh.partnersys.entity.TaskDO;
import com.zzh.partnersys.entity.UserDO;
import com.zzh.partnersys.entity.request.TaskCreateRequest;
import com.zzh.partnersys.entity.request.TaskQueryRequest;
import com.zzh.partnersys.entity.request.TaskUpdateRequest;
import com.zzh.partnersys.entity.vo.TaskVO;
import com.zzh.partnersys.mapper.TaskMapper;
import com.zzh.partnersys.mapper.UserMapper;
import com.zzh.partnersys.service.TaskService;
import com.zzh.partnersys.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import static com.zzh.partnersys.constant.UserConstant.ADMIN_ROLE;

/**
 * <p>
 * 任务表（支撑任务拆分、分配、进度跟踪） 服务实现�?
 * </p>
 *
 * @author zzh
 * @since 2025-11-01
 */
@Service
public class TaskServiceImpl extends ServiceImpl<TaskMapper, TaskDO> implements TaskService {

    @Resource
    private UserService userService;

    @Resource
    private UserMapper userMapper;

    @Override
    @Transactional
    public TaskDO createTask(TaskCreateRequest taskCreateRequest, HttpServletRequest request) {
        // 1. 获取当前用户
        UserDO currentUser = userService.getCurrentUser(request);
        if (currentUser == null) {
            throw new BusinessException(ResultCodeEnum.NO_AUTH);
        }

        // 2. 参数校验
        if (taskCreateRequest == null) {
            throw new BusinessException(ResultCodeEnum.PARAMS_ERROR);
        }
        if (StringUtils.isBlank(taskCreateRequest.getTaskTitle())) {
            throw new BusinessException(ResultCodeEnum.PARAMS_ERROR);
        }
        if (taskCreateRequest.getTeamId() == null || taskCreateRequest.getTeamId() <= 0) {
            throw new BusinessException(ResultCodeEnum.PARAMS_ERROR);
        }
        if (taskCreateRequest.getAssigneeUidList() == null || taskCreateRequest.getAssigneeUidList().isEmpty()) {
            throw new BusinessException(ResultCodeEnum.PARAMS_ERROR);
        }

        // 3. 创建任务对象
        TaskDO taskDO = new TaskDO();
        taskDO.setTaskTitle(taskCreateRequest.getTaskTitle());
        taskDO.setTeamId(taskCreateRequest.getTeamId());
        taskDO.setParentTaskId(taskCreateRequest.getParentTaskId());
        taskDO.setAssigneeUid(StringUtils.join(taskCreateRequest.getAssigneeUidList(), ","));
        taskDO.setTaskDesc(taskCreateRequest.getTaskDesc());
        taskDO.setPriority(taskCreateRequest.getPriority());
        taskDO.setStatus(taskCreateRequest.getStatus());
        taskDO.setStartTime(taskCreateRequest.getStartTime());
        taskDO.setDeadline(taskCreateRequest.getDeadline());
        taskDO.setVerifyStandard(taskCreateRequest.getVerifyStandard());
        taskDO.setCreatorUid(currentUser.getId());

        // 4. 保存任务
        boolean saved = this.save(taskDO);
        if (!saved) {
            throw new BusinessException(ResultCodeEnum.PARAMS_ERROR);
        }

        return taskDO;
    }

    @Override
    @Transactional
    public TaskDO updateTask(TaskUpdateRequest taskUpdateRequest, HttpServletRequest request) {
        // 1. 获取当前用户
        UserDO currentUser = userService.getCurrentUser(request);
        if (currentUser == null) {
            throw new BusinessException(ResultCodeEnum.NO_AUTH);
        }

        // 2. 参数校验
        if (taskUpdateRequest == null || taskUpdateRequest.getTaskId() == null || taskUpdateRequest.getTaskId() <= 0) {
            throw new BusinessException(ResultCodeEnum.PARAMS_ERROR);
        }

        // 3. 查询任务
        TaskDO taskDO = this.getById(taskUpdateRequest.getTaskId());
        if (taskDO == null) {
            throw new BusinessException(ResultCodeEnum.TASK_NOT_FOUND);
        }

        // 4. 权限检�?
        checkTaskPermission(taskDO, currentUser);

        // 5. 更新字段
        if (StringUtils.isNotBlank(taskUpdateRequest.getTaskTitle())) {
            taskDO.setTaskTitle(taskUpdateRequest.getTaskTitle());
        }
        if (taskUpdateRequest.getParentTaskId() != null) {
            taskDO.setParentTaskId(taskUpdateRequest.getParentTaskId());
        }
        if (taskUpdateRequest.getAssigneeUidList() != null && !taskUpdateRequest.getAssigneeUidList().isEmpty()) {
            taskDO.setAssigneeUid(StringUtils.join(taskUpdateRequest.getAssigneeUidList(), ","));
        }
        if (StringUtils.isNotBlank(taskUpdateRequest.getTaskDesc())) {
            taskDO.setTaskDesc(taskUpdateRequest.getTaskDesc());
        }
        if (taskUpdateRequest.getPriority() != null) {
            taskDO.setPriority(taskUpdateRequest.getPriority());
        }
        if (taskUpdateRequest.getStatus() != null) {
            taskDO.setStatus(taskUpdateRequest.getStatus());
        }
        if (taskUpdateRequest.getStartTime() != null) {
            taskDO.setStartTime(taskUpdateRequest.getStartTime());
        }
        if (taskUpdateRequest.getDeadline() != null) {
            taskDO.setDeadline(taskUpdateRequest.getDeadline());
        }
        if (StringUtils.isNotBlank(taskUpdateRequest.getVerifyStandard())) {
            taskDO.setVerifyStandard(taskUpdateRequest.getVerifyStandard());
        }
        taskDO.setUpdateTime(LocalDateTime.now());

        // 6. 保存更新
        boolean updated = this.updateById(taskDO);
        if (!updated) {
            throw new BusinessException(ResultCodeEnum.PARAMS_ERROR);
        }

        return taskDO;
    }

    @Override
    @Transactional
    public boolean deleteTask(Long taskId, HttpServletRequest request) {
        // 1. 获取当前用户
        UserDO currentUser = userService.getCurrentUser(request);
        if (currentUser == null) {
            throw new BusinessException(ResultCodeEnum.NO_AUTH);
        }

        // 2. 参数校验
        if (taskId == null || taskId <= 0) {
            throw new BusinessException(ResultCodeEnum.PARAMS_ERROR);
        }

        // 3. 查询任务
        TaskDO taskDO = this.getById(taskId);
        if (taskDO == null) {
            throw new BusinessException(ResultCodeEnum.TASK_NOT_FOUND);
        }

        // 4. 权限检�?
        checkTaskPermission(taskDO, currentUser);

        // 5. 删除任务（逻辑删除�?
        return this.removeById(taskId);
    }

    @Override
    public List<TaskVO> queryTasks(TaskQueryRequest taskQueryRequest, HttpServletRequest request) {
        // 1. 获取当前用户
        UserDO currentUser = userService.getCurrentUser(request);
        if (currentUser == null) {
            throw new BusinessException(ResultCodeEnum.NO_AUTH);
        }

        // 2. 构建查询条件
        QueryWrapper<TaskDO> queryWrapper = new QueryWrapper<>();
        if (taskQueryRequest != null) {
            // 关键词搜�?
            if (StringUtils.isNotBlank(taskQueryRequest.getKeyword())) {
                queryWrapper.like("task_title", taskQueryRequest.getKeyword());
            }
            // 团队ID
            if (taskQueryRequest.getTeamId() != null) {
                queryWrapper.eq("team_id", taskQueryRequest.getTeamId());
            }
            // 负责人ID
            if (taskQueryRequest.getAssigneeUid() != null) {
                queryWrapper.like("assignee_uid", "," + taskQueryRequest.getAssigneeUid() + ",")
                        .or().like("assignee_uid", taskQueryRequest.getAssigneeUid() + ",")
                        .or().like("assignee_uid", "," + taskQueryRequest.getAssigneeUid())
                        .or().eq("assignee_uid", taskQueryRequest.getAssigneeUid());
            }
            // 优先�?
            if (taskQueryRequest.getPriority() != null) {
                queryWrapper.eq("priority", taskQueryRequest.getPriority());
            }
            // 状�?
            if (taskQueryRequest.getStatus() != null) {
                queryWrapper.eq("status", taskQueryRequest.getStatus());
            }
            // 开始时间范�?
            if (taskQueryRequest.getStartTimeFrom() != null) {
                queryWrapper.ge("start_time", taskQueryRequest.getStartTimeFrom());
            }
            if (taskQueryRequest.getStartTimeTo() != null) {
                queryWrapper.le("start_time", taskQueryRequest.getStartTimeTo());
            }
            // 截止时间范围
            if (taskQueryRequest.getDeadlineFrom() != null) {
                queryWrapper.ge("deadline", taskQueryRequest.getDeadlineFrom());
            }
            if (taskQueryRequest.getDeadlineTo() != null) {
                queryWrapper.le("deadline", taskQueryRequest.getDeadlineTo());
            }
            // 排序
            if (StringUtils.isNotBlank(taskQueryRequest.getSortField())) {
                boolean isAsc = "asc".equalsIgnoreCase(taskQueryRequest.getSortOrder());
                queryWrapper.orderBy(true, isAsc, taskQueryRequest.getSortField());
            } else {
                // 默认排序
                queryWrapper.orderByDesc("priority", "update_time");
            }
        }

        // 3. 执行查询
        List<TaskDO> taskDOList = this.list(queryWrapper);

        // 4. 转换为VO
        return convertToTaskVOList(taskDOList);
    }

    @Override
    public TaskVO getTaskDetail(Long taskId, HttpServletRequest request) {
        // 1. 获取当前用户
        UserDO currentUser = userService.getCurrentUser(request);
        if (currentUser == null) {
            throw new BusinessException(ResultCodeEnum.NO_AUTH);
        }

        // 2. 参数校验
        if (taskId == null || taskId <= 0) {
            throw new BusinessException(ResultCodeEnum.PARAMS_ERROR);
        }

        // 3. 查询任务
        TaskDO taskDO = this.getById(taskId);
        if (taskDO == null) {
            throw new BusinessException(ResultCodeEnum.TASK_NOT_FOUND);
        }

        // 4. 转换为VO
        List<TaskVO> taskVOList = convertToTaskVOList(Arrays.asList(taskDO));
        return taskVOList.isEmpty() ? null : taskVOList.get(0);
    }

    @Override
    @Transactional
    public boolean updateTaskProgress(Long taskId, Integer progress, HttpServletRequest request) {
        // 1. 获取当前用户
        UserDO currentUser = userService.getCurrentUser(request);
        if (currentUser == null) {
            throw new BusinessException(ResultCodeEnum.NO_AUTH);
        }

        // 2. 参数校验
        if (taskId == null || taskId <= 0 || progress == null || progress < 0 || progress > 100) {
            throw new BusinessException(ResultCodeEnum.PARAMS_ERROR);
        }

        // 3. 查询任务
        TaskDO taskDO = this.getById(taskId);
        if (taskDO == null) {
            throw new BusinessException(ResultCodeEnum.TASK_NOT_FOUND);
        }

        // 权限检查（负责人可以更新进度）
        if (!isAssigneeOrCreator(taskDO, currentUser)) {
            throw new BusinessException(ResultCodeEnum.PARAMS_ERROR);
        }

        // 5. 更新进度
        taskDO.setProgress(progress);
        taskDO.setUpdateTime(LocalDateTime.now());

        // 如果进度�?00，自动设置状态为已完�?
        if (progress == 100) {
            taskDO.setStatus(2);
        }

        return this.updateById(taskDO);
    }

    @Override
    @Transactional
    public boolean updateTaskStatus(Long taskId, Integer status, HttpServletRequest request) {
        // 1. 获取当前用户
        UserDO currentUser = userService.getCurrentUser(request);
        if (currentUser == null) {
            throw new BusinessException(ResultCodeEnum.NO_AUTH);
        }

        // 2. 参数校验
        if (taskId == null || taskId <= 0 || status == null || status < 0 || status > 3) {
            throw new BusinessException(ResultCodeEnum.PARAMS_ERROR);
        }

        // 3. 查询任务
        TaskDO taskDO = this.getById(taskId);
        if (taskDO == null) {
            throw new BusinessException(ResultCodeEnum.TASK_NOT_FOUND);
        }

        // 4. 权限检�?
        checkTaskPermission(taskDO, currentUser);

        // 5. 更新状�?
        taskDO.setStatus(status);
        taskDO.setUpdateTime(LocalDateTime.now());

        // 如果状态为已完成，自动设置进度�?00
        if (status == 2) {
            taskDO.setProgress(100);
        }

        return this.updateById(taskDO);
    }

    @Override
    public List<TaskVO> getUserTasks(Long userId, HttpServletRequest request) {
        // 1. 获取当前用户
        UserDO currentUser = userService.getCurrentUser(request);
        if (currentUser == null) {
            throw new BusinessException(ResultCodeEnum.NO_AUTH);
        }

        // 2. 参数校验
        if (userId == null || userId <= 0) {
            throw new BusinessException(ResultCodeEnum.PARAMS_ERROR);
        }

//        // 权限检查（只能查看自己的任务）
//        if (!currentUser.getId().equals(userId) && !currentUser.getUserRole().equals(ADMIN_ROLE)) {
//            throw new BusinessException(ResultCodeEnum.PARAMS_ERROR);
//        }

        // 4. 查询任务
        QueryWrapper<TaskDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.like("assignee_uid", "," + userId + ",")
                .or().like("assignee_uid", userId + ",")
                .or().like("assignee_uid", "," + userId)
                .or().eq("assignee_uid", userId);
        queryWrapper.orderByDesc("priority", "deadline");

        List<TaskDO> taskDOList = this.list(queryWrapper);

        // 5. 转换为VO
        return convertToTaskVOList(taskDOList);
    }

    @Override
    public List<TaskVO> getTasksByAssignee(Long assigneeUid, HttpServletRequest request) {
        // 1. 获取当前用户
        UserDO currentUser = userService.getCurrentUser(request);
        if (currentUser == null) {
            throw new BusinessException(ResultCodeEnum.NO_AUTH);
        }

        // 2. 参数校验
        if (assigneeUid == null || assigneeUid <= 0) {
            throw new BusinessException(ResultCodeEnum.PARAMS_ERROR);
        }

        // 3. 查询任务
        QueryWrapper<TaskDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.like("assignee_uid", "," + assigneeUid + ",")
                .or().like("assignee_uid", assigneeUid + ",")
                .or().like("assignee_uid", "," + assigneeUid)
                .or().eq("assignee_uid", assigneeUid);
        queryWrapper.orderByDesc("priority", "deadline");

        List<TaskDO> taskDOList = this.list(queryWrapper);

        // 4. 转换为VO
        return convertToTaskVOList(taskDOList);
    }

    @Override
    public List<TaskVO> getTeamTasks(Long teamId, HttpServletRequest request) {
        // 1. 获取当前用户
        UserDO currentUser = userService.getCurrentUser(request);
        if (currentUser == null) {
            throw new BusinessException(ResultCodeEnum.NO_AUTH);
        }

        // 2. 参数校验
        if (teamId == null || teamId <= 0) {
            throw new BusinessException(ResultCodeEnum.PARAMS_ERROR);
        }

        // 3. 查询任务
        QueryWrapper<TaskDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("team_id", teamId);
        queryWrapper.orderByDesc("priority", "update_time");

        List<TaskDO> taskDOList = this.list(queryWrapper);

        // 4. 转换为VO
        return convertToTaskVOList(taskDOList);
    }

    /**
     * 检查任务权�?
     */
    private void checkTaskPermission(TaskDO taskDO, UserDO currentUser) {
        // 管理员或创建者有编辑权限
        if (!currentUser.getUserRole().equals(ADMIN_ROLE) && !currentUser.getId().equals(taskDO.getCreatorUid())) {
            throw new BusinessException(ResultCodeEnum.PARAMS_ERROR);
        }
    }

    /**
     * 判断用户是否为任务负责人或创建�?
     */
    private boolean isAssigneeOrCreator(TaskDO taskDO, UserDO currentUser) {
        // 创建者有所有权�?
        if (currentUser.getId().equals(taskDO.getCreatorUid()) || currentUser.getUserRole().equals(ADMIN_ROLE)) {
            return true;
        }
        // 检查是否为负责�?
        String assigneeUid = taskDO.getAssigneeUid();
        if (StringUtils.isNotBlank(assigneeUid)) {
            List<String> assigneeList = Arrays.asList(assigneeUid.split(","));
            return assigneeList.contains(currentUser.getId().toString());
        }
        return false;
    }

    /**
     * 将TaskDO列表转换为TaskVO列表
     */
    private List<TaskVO> convertToTaskVOList(List<TaskDO> taskDOList) {
        if (taskDOList == null || taskDOList.isEmpty()) {
            return new ArrayList<>();
        }

        List<TaskVO> taskVOList = new ArrayList<>();
        LocalDateTime now = LocalDateTime.now();

        for (TaskDO taskDO : taskDOList) {
            TaskVO taskVO = new TaskVO();
            taskVO.setId(taskDO.getId());
            taskVO.setTaskTitle(taskDO.getTaskTitle());
            taskVO.setTeamId(taskDO.getTeamId());
            taskVO.setParentTaskId(taskDO.getParentTaskId());
            taskVO.setAssigneeUid(taskDO.getAssigneeUid());
            taskVO.setTaskDesc(taskDO.getTaskDesc());
            taskVO.setPriority(taskDO.getPriority());
            taskVO.setStatus(taskDO.getStatus());
            taskVO.setStartTime(taskDO.getStartTime());
            taskVO.setDeadline(taskDO.getDeadline());
            taskVO.setProgress(taskDO.getProgress());
            taskVO.setVerifyStandard(taskDO.getVerifyStandard());
            taskVO.setCreatorUid(taskDO.getCreatorUid());
            taskVO.setCreateTime(taskDO.getCreateTime());
            taskVO.setUpdateTime(taskDO.getUpdateTime());
            taskVO.setIsDelete(taskDO.getIsDelete());

            // 设置负责人信�?
            if (StringUtils.isNotBlank(taskDO.getAssigneeUid())) {
                List<Long> assigneeIdList = Arrays.stream(taskDO.getAssigneeUid().split(","))
                        .map(Long::parseLong)
                        .collect(Collectors.toList());
                List<UserDO> assigneeList = userMapper.selectByIds(assigneeIdList);
                taskVO.setAssigneeList(assigneeList.stream().map(userService::getSafeUser).collect(Collectors.toList()));
            }

            // 设置创建者信�?
            UserDO creator = userMapper.selectById(taskDO.getCreatorUid());
            if (creator != null) {
                taskVO.setCreator(userService.getSafeUser(creator));
            }

            // 判断是否过期
            if (taskDO.getDeadline() != null && taskDO.getStatus() != 2 && now.isAfter(taskDO.getDeadline())) {
                taskVO.setIsExpired(true);
            } else {
                taskVO.setIsExpired(false);
            }

            taskVOList.add(taskVO);
        }

        return taskVOList;
    }
}
